package top.ijiujiu.config;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.SneakyThrows;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.RestControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import top.ijiujiu.exception.DefaultException;
import top.ijiujiu.util.ResultUtil;

/**
 * 统一封装响应数据
 *
 * @Author 神秘的黄瓜
 * @Version 1.0
 * @Date 2020-08-24 11:20
 */
// 注意哦，这里要加上需要扫描的包
@RestControllerAdvice(basePackages = {"top.ijiujiu.controller"})
public class ResponseControllerAdvice implements ResponseBodyAdvice<Object> {


    /**
     * 如果接口返回的类型本身就是ResultUtil那就没有必要进行额外的操作，返回false
     *
     * @param returnType
     * @param aClass
     * @return
     */
    @Override
    public boolean supports(MethodParameter returnType, Class<? extends HttpMessageConverter<?>> aClass) {
        return !returnType.getParameterType().equals(ResultUtil.class);
    }

    /**
     * 将原本的数据包装在ResultUtil里
     *
     * @param data
     * @param returnType
     * @param mediaType
     * @param aClass
     * @param request
     * @param response
     * @return
     */
    @SneakyThrows
    @Override
    public Object beforeBodyWrite(Object data, MethodParameter returnType, MediaType mediaType,
                                  Class<? extends HttpMessageConverter<?>> aClass, ServerHttpRequest request, ServerHttpResponse response) {
        // String类型不能直接包装，所以要进行些特别的处理
        if (returnType.getGenericParameterType().equals(String.class)) {
            ObjectMapper objectMapper = new ObjectMapper();
            try {
                // 将数据包装在ResultUtil里后，再转换为JSON字符串响应给前端
                return objectMapper.writeValueAsString(new ResultUtil<>(data));
            } catch (JsonProcessingException e) {
                throw new DefaultException("返回String类型错误~~~~~~");
            }
        }
        return new ResultUtil<>(data);
    }
}